home *** CD-ROM | disk | FTP | other *** search
- /*======================================================================
- *
- * FILE:
- * stubutil.c
- *
- * IDENTIFICATION
- * $Header: /private/postgres/src/rules/stubs/RCS/stubutil.c,v 1.9 1991/11/18 22:22:25 mer Exp $
- *
- * DESCRIPTION:
- *
- * some general utility routines for the world famous 'stub records'
- *
- *======================================================================
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include "utils/log.h"
- #include "utils/palloc.h"
- #include "tmp/postgres.h"
- #include "tmp/datum.h"
- #include "rules/prs2.h"
- #include "rules/prs2stub.h"
- #include "nodes/primnodes.h"
- #include "nodes/primnodes.a.h"
-
- extern Node CopyObject();
- extern bool _equalLispValue();
-
- /*-------------------------------------------------------------------
- *
- * prs2StubQualIsEqual
- *
- * Returns true if the two stub qualifications given are
- * equal.
- *
- * NOTE: see restrictions in 'datumIsEqual' for testing whether
- * two datums are equal...
- *
- *-------------------------------------------------------------------
- */
- bool
- prs2StubQualIsEqual(q1, q2)
- LispValue q1;
- LispValue q2;
- {
- if (_equalLispValue(q1, q2))
- return(true);
- else
- return(false);
- }
-
- /*-------------------------------------------------------------------
- *
- * prs2OneStubIsEqual
- *
- * return true if the two 'Prs2OneStub's are the same
- *
- * NOTE1: we don't check the 'counter' field
- * NOTE2: we don't check the 'lock' field either, because if
- * 2 stub records have the same 'ruleId' and 'stubId' they are
- * guaranteed to have the same lock!
- *-------------------------------------------------------------------
- */
- bool
- prs2OneStubIsEqual(stub1, stub2)
- Prs2OneStub stub1;
- Prs2OneStub stub2;
- {
- int i;
-
- if (stub1->ruleId != stub2->ruleId) {
- return(false);
- }
- if (stub1->stubId != stub2->stubId) {
- return(false);
- }
-
- /*
- * Test the qualifications...
- */
- if (!prs2StubQualIsEqual(stub1->qualification, stub2->qualification)) {
- return(false);
- }
-
- return(true);
- }
-
- /*-------------------------------------------------------------------
- *
- * prs2SearchStub
- *
- * Given a 'Prs2Stub' search and return he index to the 'Prs2OneStub' which
- * is equal to the given 'Prs2OneStub'
- * If no such 'Prs2OneStub; exists, then return -1
- *
- *-------------------------------------------------------------------
- */
- int
- prs2SearchStub(stubs, oneStub)
- Prs2Stub stubs;
- Prs2OneStub oneStub;
- {
- int i;
- for (i=0; i<stubs->numOfStubs; i++) {
- if (prs2OneStubIsEqual(oneStub, stubs->stubRecords[i])) {
- /*
- * We've found it! Return its index
- */
- return(i);
- }
- }
- /*
- * Nop! We didn't find it!
- */
- return(-1);
- }
-
- /*-------------------------------------------------------------------
- *
- * prs2AddOneStub
- *
- * Add a new stub record.
- * Note that it is possible to have many copies of the same
- * stub record. Therefore before phusically appending the new stub,
- * see if a similar copy already exists. If yes, then
- * just increment the appropriate counter.
- *
- * NOTE: We do NOT make a copy of the 'newStub'. So do NOT pfree
- * anything contained in there !
- *-------------------------------------------------------------------
- */
- void
- prs2AddOneStub(oldStubs, newStub)
- Prs2Stub oldStubs;
- Prs2OneStub newStub;
- {
- int i;
- Prs2OneStub s;
- int indx;
- Prs2OneStub *temp;
- int n;
-
- /*
- * does this stub already exist ?
- */
- indx = prs2SearchStub(oldStubs, newStub);
- if (indx >=0) {
- /*
- * this record already exists.
- * Increment its counter and return
- */
- oldStubs->stubRecords[i]->counter += 1;
- return;
- }
- /*
- * this stub record did not exist. We must create a
- * completely new entry...
- * NOTE: 'Prs2Stub->stubRecords' is an array of POINTERS to
- * the 'Prs2OneStubData' records.
- */
- n = oldStubs->numOfStubs;
- temp = (Prs2OneStub *) palloc((n+1) * sizeof(Prs2OneStub));
- for (i=0; i<n; i++) {
- temp[i] = oldStubs->stubRecords[i];
- }
- temp[n] = newStub;
- /*
- * pfree the old array of pointers and replace it with the
- * new one 'temp'.
- */
- if (oldStubs->numOfStubs > 0 && oldStubs->stubRecords != NULL)
- pfree((Pointer)oldStubs->stubRecords);
- oldStubs->stubRecords = temp;
- oldStubs->numOfStubs+= 1;
-
- }
-
- /*-------------------------------------------------------------------
- *
- * prs2DeleteOneStub
- *
- * Delete a stub record.
- *-------------------------------------------------------------------
- */
- void
- prs2DeleteOneStub(oldStubs, oldStub)
- Prs2Stub oldStubs;
- Prs2OneStub oldStub;
- {
- int i;
- Prs2OneStub s;
- int n;
- int indx;
-
- /*
- * does this stub already exist ?
- */
- indx = prs2SearchStub(oldStubs, oldStub);
- if (indx < 0) {
- /*
- * No such record existed. complain!
- */
- elog(WARN,"prs2DeleteOneStub: stub not found");
- }
-
- /*
- * So, this record already existed.
- * Decrement its counter.
- */
- s = oldStubs->stubRecords[i];
- (s->counter)--;
-
- /*
- * if the counter is non zero, we are done
- */
- if (s->counter > 0) {
- return;
- }
-
- /*
- * else we must physically delete this record
- *
- * Move the pointer entry of the last stub record to the one to be
- * deleted and decrement the number of stub records.
- * Don't forget to free the 'oneStub'
- */
- n = oldStubs->numOfStubs;
- pfree((Pointer)oldStubs->stubRecords[indx]);
- oldStubs->stubRecords[indx] = oldStubs->stubRecords[n-1];
- oldStubs->numOfStubs -= 1;
-
- }
-
- /*-----------------------------------------------------------------------
- *
- * prs2MakeStub
- *
- * create an (empty) stub record
- *
- *-----------------------------------------------------------------------
- */
- Prs2Stub
- prs2MakeStub()
- {
- Prs2Stub res;
-
- res = (Prs2Stub) palloc(sizeof(Prs2StubData));
- if (res == NULL) {
- elog(WARN, "prs2MakeStub: Out of memory\n");
- }
- res->numOfStubs = 0;
- res->stubRecords = NULL;
-
- return(res);
- }
-
- /*-----------------------------------------------------------------------
- *
- * prs2MakeOneStub
- *
- * create an initialized Prs2OneStub record.
- *
- *-----------------------------------------------------------------------
- */
- Prs2OneStub
- prs2MakeOneStub()
- {
- Prs2OneStub res;
-
- res = (Prs2OneStub) palloc(sizeof(Prs2OneStubData));
- if (res == NULL) {
- elog(WARN, "prs2MakeOneStub: Out of memory\n");
- }
-
- return(res);
- }
-
- /*-----------------------------------------------------------------------
- *
- * prs2FreeStub
- *
- * free all space occupied by a stub record
- *-----------------------------------------------------------------------
- */
- void
- prs2FreeStub(relstub)
- Prs2Stub relstub;
- {
- int i,j;
- Prs2OneStub oneStub;
-
- Assert(PointerIsValid(relstub));
-
- /*
- * One by one free all the 'Prs2OneStub' structs.
- */
- for (i=0; i<relstub->numOfStubs; i++) {
- oneStub = relstub->stubRecords[i];
- #ifdef STUB_DEBUG
- bzero(oneStub, sizeof(Prs2OneStubData));
- #endif STUB_DEBUG
- pfree((Pointer)oneStub);
- }
-
- if (relstub->numOfStubs>0 && relstub->stubRecords != NULL) {
- pfree((Pointer)relstub->stubRecords);
- }
-
- #ifdef STUB_DEBUG
- bzero(relstub, sizeof(Prs2StubData));
- #endif STUB_DEBUG
- pfree((Pointer)relstub);
- }
-
- /*----------------------------------------------------------------------
- * prs2RemoveStubsOfRule
- *
- * Remove the stubs of the given rule (in place).
- * If no stubs of this rule were found return false, else true.
- *----------------------------------------------------------------------
- */
- bool
- prs2RemoveStubsOfRule(stubs, ruleId)
- Prs2Stub stubs;
- ObjectId ruleId;
- {
- int i;
- Prs2OneStub thisStub;
- bool result;
-
- result = false;
- i=0;
- while (i<stubs->numOfStubs) {
- thisStub = stubs->stubRecords[i];
- if (thisStub->ruleId == ruleId) {
- /*
- * remove this stub by copying over it the last stub
- * The result is more or less similar to moving all the
- * stubs above the one to be deleted, one place down.
- * So, we must NOT increment 'i' !
- */
- result = true;
- stubs->stubRecords[i] = stubs->stubRecords[stubs->numOfStubs-1];
- pfree((Pointer)thisStub);
- stubs->numOfStubs -=1;
- } else {
- /*
- * examine the next stub...
- */
- i++;
- }
- }
-
- return(result);
- }
-
-